package com.odontosis.view.servico;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.LabelValueBean;

import com.odontosis.acesso.filtro.PermissaoAcesso;
import com.odontosis.entidade.GrupoUsuario;
import com.odontosis.entidade.Pagamento;
import com.odontosis.entidade.Procedimento;
import com.odontosis.entidade.Servico;
import com.odontosis.entidade.StatusServico;
import com.odontosis.entidade.TipoServico;
import com.odontosis.entidade.Usuario;
import com.odontosis.ioc.ContainerIoc;
import com.odontosis.service.PacienteService;
import com.odontosis.service.PagamentoService;
import com.odontosis.service.ServicoService;
import com.odontosis.util.StringUtilsOdontosis;
import com.odontosis.view.OdontosisAction;

/**
 * Ao de cadastro de servico.
 * @author Oto
 *
 */
public class AcaoCadastroServico extends OdontosisAction<ServicoService> {
	
	private Servico servico;
	
	private boolean geradoServico = false;
	
	/**
	 * Mtodo principal da ao. 
	 */
	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormCadastroServico form = (FormCadastroServico) actionForm;
		carregarRadiosTiposServico(request);
		
		
		if(!StringUtilsOdontosis.isVazia(form.getAlteracao())){
			Servico servico = service.load(new Long(form.getAlteracao()));
			form.setIsentar(servico.isIsento());
			service.evict(servico);
		}
		if(StringUtilsOdontosis.isVazia(form.getMetodo())){
			return onIniciar(mapping, actionForm, request, response);
		}
		if(form.getMetodo().equals("isentar")){
			return onIsentar(mapping, actionForm, request, response);
		}
		if(form.getMetodo().equals("orcamento")){
			return onSalvarOrcamento(mapping, actionForm, request, response);
		}
		if(form.getMetodo().equals("gerar")){
			return onGerarServico(mapping, actionForm, request, response);
		}
		if(form.getMetodo().equals("add")){
			return onAdicionar(mapping, actionForm, request, response);
		}
		if(form.getMetodo().equals("editar")){
			return onEditar(mapping, actionForm, request, response);
		}
		return super.execute(mapping, actionForm, request, response);
	}
	
	
	public ActionForward onAdicionar(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormCadastroServico form = (FormCadastroServico) actionForm;
		form.setTipo("5");
		long id = Long.parseLong(form.getProcedimento());
		List<Procedimento> procedimentos = new ArrayList<Procedimento>();
		if(request.getSession().getAttribute("proc") == null){
			request.getSession().setAttribute("proc", procedimentos);
		}else{
			procedimentos = (List<Procedimento>) request.getSession().getAttribute("proc");
		}
		procedimentos.add(ContainerIoc.getProcedimentoService().load(id));
		request.setAttribute("colecaoProcedimentos", procedimentos);
		return mapping.getInputForward();
	}
	
	public ActionForward onGerarServico(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormCadastroServico form = (FormCadastroServico) actionForm;
		form.setOrcamento(true);
		geradoServico = true;
		return salvar(mapping, form, request, response);
	}
	
	public ActionForward onIsentar(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		FormCadastroServico form = (FormCadastroServico) actionForm;
		
		//Usuario usuario = (Usuario) request.getSession().getAttribute("usuario");
		PermissaoAcesso.verificarAcesso(mapping, form, request, response, GrupoUsuario.ADMIN, GrupoUsuario.THD);
		
		Servico servico = service.load(new Long(form.getAlteracao()));
		servico.setIsento(true);
		Integer mesIsencao = Integer.parseInt(form.getMesIsencao());
		Integer anoIsencao = Integer.parseInt(form.getAnoIsencao());
		servico.setMesIsencao(mesIsencao);
		servico.setAnoIsencao(anoIsencao);
		service.update(servico);
		PagamentoService pagService = ContainerIoc.getPagamentoService();
		for(Pagamento pagamento : servico.getListaPagamentos()){
			if((pagamento.getMesVencimento().intValue() >= servico.getMesIsencao().intValue() && pagamento.getAnoVencimento().intValue() >= servico.getAnoIsencao().intValue()) || pagamento.getAnoVencimento().intValue() > servico.getAnoIsencao().intValue()){
				if(!pagamento.isPago()){
					pagamento.setAtivo(false);
					pagService.update(pagamento);
				}
			}
		}
		
		form.setIsentar(true);
		//form.setIsentarAgora(false);
		Collection<String> sucesso = new ArrayList<String>();
		sucesso.add("O serviço foi isento com sucesso.");
		request.setAttribute("sucesso", sucesso);
		request.setAttribute("mensagens", null);
		request.setAttribute("colecaoProcedimentos", form.getProcedimentos());
		return onIniciar(mapping, actionForm, request, response);
	}
	
	
	/**
	 * Carrega radios de tipos de servio.
	 * @param request Requisio HTTP.
	 */
	private void carregarRadiosTiposServico(HttpServletRequest request) {
		TipoServico[] tiposServico = TipoServico.values();
		List<LabelValueBean> valueBeans = new ArrayList<LabelValueBean>();
		for (TipoServico tipoServico : tiposServico) {
			valueBeans.add(new LabelValueBean(
				tipoServico.getDescricao(),
				String.valueOf(tipoServico.getId())));
		}
		request.getSession().setAttribute("tiposServico", valueBeans);
	}


	/**
	 * Mtodo de visualizar.
	 * @param mapping
	 * @param actionForm
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward visualizar(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		log.debug("Disparado mtodo \'visualizar\'");
		
		FormCadastroServico form = (FormCadastroServico)actionForm;
		form.setEditavel(Boolean.TRUE.toString());
		ActionForward forward = mapping.getInputForward();
		
		log.debug("Fim de mtodo \'visualizar\'");
		log.debug("Forward - name:" + forward.getName() + " path:" + forward.getPath());
		
		return forward;
	}
	
	/**
	 * Mtodo de edio.
	 * @param mapping
	 * @param actionForm
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward onEditar(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormCadastroServico form = (FormCadastroServico)actionForm;
		
		Servico servico = service.load(Long.parseLong(form.getAlteracao()));
		
		PermissaoAcesso.verificarAcesso(mapping, actionForm, request, response, GrupoUsuario.ADMIN, GrupoUsuario.SECRETARIA, GrupoUsuario.THD);
		
		
		//se serviço finalizado gera e isenta as parcelas posteriores ao mes atual
		if(!StringUtilsOdontosis.isVazia(form.getStatus()) && form.getStatus().trim().equals("1")) {
			ContainerIoc.getPagamentoService().gerarTaxasManutencao(servico.getPacienteServico());
			servico = service.load(Long.parseLong(form.getAlteracao()));
			isentarPosteriores(servico);
		}
		
		//inserir campos que são editaveis
		if(form.isIsentarAgora()){
			PermissaoAcesso.verificarAcesso(mapping, actionForm, request, response, GrupoUsuario.ADMIN, GrupoUsuario.THD);
			servico = isentar(form, servico);
		}else{
			servico.setIsento(false);
		}
		Integer status = StringUtilsOdontosis.isVazia(form.getStatus()) ? null : Integer.parseInt(form.getStatus());
		servico.setStatusServico(StatusServico.recuperarPorId(status));
		
		
		service.update(servico);
		Collection<String> sucesso = new ArrayList<String>();
		sucesso.add("Registro Atualizado com sucesso.");
		request.setAttribute("sucesso", sucesso);
		request.setAttribute("mensagens", null);
		return mapping.findForward("lista");
	}
	
	/**
	 * Mtodo de salvar.
	 * @param mapping
	 * @param actionForm
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward salvar(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormCadastroServico form = (FormCadastroServico)actionForm;
		PacienteService pacienteService = new PacienteService();
		//if(servico == null){
		servico = new Servico();
		//}
		Long id = servico.getId();
		
		
		form.transferirParaBOs(form, servico);
		form.setEditavel(Boolean.TRUE.toString());
		if(id == null || id.equals(new Long(0))){
			servico.setId(null);
		}else{
			servico.setId(null);
			ServicoService servicoService = new ServicoService();
			servicoService.evict(servico);
		}
		
		
		
		servico.setPacienteServico(pacienteService.load(Long.parseLong(form.getPaciente())));
		servico.setTipoServico(TipoServico.recuperarPorId(Integer.parseInt(form.getTipo())));
		Long alter = null;
		if(!StringUtilsOdontosis.isVazia(form.getAlteracao())){
			alter = new Long(form.getAlteracao());
		}
		
		//seta null nos valores nao preenchidos
		if(servico.getValorInicial().trim().isEmpty()){
			servico.setValorInicial(null);
		}
		if(servico.getQuantidadeInicial().trim().isEmpty()){
			servico.setQuantidadeInicial(null);
		}
		
		servico.setIsento(form.isIsentar());
		servico.setOrcamento(false);
		servico.setStatusServico(StatusServico.EM_ANDAMENTO);
		
		service.saveOrUpdate(servico,alter,form.isentarAgora);
		
		//ContainerIoc.getPagamentoService().gerarTaxasManutencao(servico.getPacienteServico());
		
		Collection<String> sucesso = new ArrayList<String>();
		if(form.isOrcamento()){
			sucesso.add("Serviço gerado com Sucesso.");
		}else{
			sucesso.add("Registro Atualizado com Sucesso");
		}
		request.setAttribute("sucesso", sucesso);
		request.setAttribute("mensagens", null);
		
		ActionForward forward = null;
		if(geradoServico) {
			forward = mapping.findForward("servico");
		} else {
			forward = mapping.findForward("lista");
		}
		return forward;
	}
	
	public void isentarPosteriores(Servico servico) {
		ServicoService service = null;
		PagamentoService pagService = null;
		try{
			service = ContainerIoc.getServicoService();
			pagService = ContainerIoc.getPagamentoService();
		}catch (Exception e) {
		}
		Calendar calendar = Calendar.getInstance();
		int mesIsencaoServico = calendar.get(Calendar.MONTH) + 1;
		int anoIsencaoServico = calendar.get(Calendar.YEAR);
		
		for(Pagamento pagamento : servico.getListaPagamentos()){
			if((pagamento.getMesVencimento().intValue() >= mesIsencaoServico && pagamento.getAnoVencimento().intValue() >= anoIsencaoServico) || pagamento.getAnoVencimento().intValue() > anoIsencaoServico){
				if(!pagamento.isPago()){
					pagamento.setAtivo(false);
					pagService.update(pagamento);
				}
			}
		}
		
	}
	
	
	public Servico isentar(FormCadastroServico form, Servico servico){
		ServicoService service = null;
		PagamentoService pagService = null;
		try{
			service = ContainerIoc.getServicoService();
			pagService = ContainerIoc.getPagamentoService();
		}catch (Exception e) {
		}
		servico.setIsento(true);
		form.setIsentar(true);
		Integer mesIsencao = Integer.parseInt(form.getMesIsencao());
		Integer anoIsencao = Integer.parseInt(form.getAnoIsencao());
		servico.setMesIsencao(mesIsencao);
		servico.setAnoIsencao(anoIsencao);
		
		
		for(Pagamento pagamento : servico.getListaPagamentos()){
			int mesIsencaoServico = servico.getMesIsencao().intValue();
			int anoIsencaoServico = servico.getAnoIsencao().intValue();
			if((pagamento.getMesVencimento().intValue() >= mesIsencaoServico && pagamento.getAnoVencimento().intValue() >= anoIsencaoServico) || pagamento.getAnoVencimento().intValue() > anoIsencaoServico){
				if(!pagamento.isPago()){
					pagamento.setAtivo(false);
					pagService.update(pagamento);
				}
			}
		}
		
		service.update(servico);
		
		form.setIsentar(true);
		return servico;
	
	}
	
	/**
	 * Mtodo de salvar orçamentos.
	 * @param mapping
	 * @param actionForm
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward onSalvarOrcamento(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormCadastroServico form = (FormCadastroServico)actionForm;
		PacienteService pacienteService = new PacienteService();
		//if(servico == null){
		servico = new Servico();
		//}
		Long id = servico.getId();
		
		
		form.transferirParaBOs(form, servico);
		form.setEditavel(Boolean.TRUE.toString());
		if(id == null || id.equals(new Long(0))){
			servico.setId(null);
		}else{
			servico.setId(null);
			ServicoService servicoService = new ServicoService();
			servicoService.evict(servico);
		}
		
		
		
		servico.setPacienteServico(pacienteService.load(Long.parseLong(form.getPaciente())));
		servico.setTipoServico(TipoServico.recuperarPorId(Integer.parseInt(form.getTipo())));
		Long alter = null;
		if(!StringUtilsOdontosis.isVazia(form.getAlteracao())){
			alter = new Long(form.getAlteracao());
		}
		
		//seta null nos valores nao preenchidos
		if(servico.getValorInicial().trim().isEmpty()){
			servico.setValorInicial(null);
		}
		if(servico.getQuantidadeInicial().trim().isEmpty()){
			servico.setQuantidadeInicial(null);
		}
		servico.setStatusServico(StatusServico.EM_ANDAMENTO);
		servico.setOrcamento(true);
		service.saveOrUpdate(servico,alter,false);
		
		
		form.resetar();
		form = new FormCadastroServico();
		Collection<String> sucesso = new ArrayList<String>();
		sucesso.add("Registro Atualizado Com Sucesso");
		request.setAttribute("sucesso", sucesso);
		request.setAttribute("mensagens", null);
		
		ActionForward forward = mapping.findForward("lista");
		return forward;
	}
	
	protected ActionForward onIniciar(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
 		FormCadastroServico formulario = (FormCadastroServico)actionForm;
 		request.setAttribute("colecaoProcedimentos", formulario.getProcedimento());
 		formulario.setEditavel(Boolean.TRUE.toString());
 		if(!StringUtilsOdontosis.isVazia(formulario.getAlteracao())){
 			PermissaoAcesso.verificarAcesso(mapping, actionForm, request, response, GrupoUsuario.ADMIN, GrupoUsuario.SECRETARIA);
 		}
 		 
		if(!StringUtilsOdontosis.isVazia(formulario.getAlteracao()) && !formulario.isentarAgora){
			servico = service.load(new Long(formulario.getAlteracao()));
	//		if(servico != null){				
				//formulario.transferirParaBOs(formulario, servico);
				formulario.setAnoVencimentoPrimeiraParcela(servico.getAnoVencimentoPrimeiraParcela().toString());
				formulario.setMesVencimentoPrimeiraParcela(servico.getMesVencimentoPrimeiraParcela().toString());
				formulario.setValorInicial(servico.getValorInicial());
				formulario.setPaciente(servico.getPacienteServico().getId().toString());
				formulario.setQuantidadeParcelas(servico.getQuantidadeParcelas().toString());
				formulario.setValor(servico.getValor().toString());
				formulario.setTipo(servico.getTipoServico().getId().toString());
			    formulario.setPacienteNome(servico.getPacienteServico().getNome());
			    formulario.setQuantidadeInicial(servico.getQuantidadeInicial());
			    formulario.setMesIsencao(servico.getMesIsencao() !=null ?servico.getMesIsencao().toString():"");
			    formulario.setAnoIsencao(servico.getAnoIsencao()!= null ? servico.getAnoIsencao().toString(): "");
			    formulario.setConvenio(servico.getConvenio());
			    formulario.setIsentar(servico.isIsento());
			    formulario.setDescricao(servico.getDescricao());
			    formulario.setEditavel(Boolean.FALSE.toString());
			    formulario.setStatus(servico.getStatusServico().getId().toString());
		//	}
		}
		

		return mapping.getInputForward();
	}
	
	@Override
	protected ActionForward unspecified(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		FormCadastroServico form = (FormCadastroServico)actionForm;
		form.setEditavel(Boolean.TRUE.toString());
		return super.unspecified(mapping, form, request, response);
	}
}
